package top.lywivan.netty.reactor;

import lombok.extern.slf4j.Slf4j;
import top.lywivan.netty.reactor.cnxn.ServerCnxnFactory;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * 参考 zk 的写法
 */
@Slf4j
public class ServerMain {

    public static void main(String[] args) {
        ServerMain main = new ServerMain();
        main.initializeAndRun(args);
    }

    protected void initializeAndRun(String[] args) {
        try {
            // 根据参数解析配置
            ServerConfig config = new ServerConfig();
            if (args.length ==0) {
                //解析配置文件，并创建IntSocketAddress对象
                config.parse();
            }else if (args.length == 1) {
                config.parse(args[0]);
            }else {
                config.parse(args);
            }

            //根据配置运行
            runFromConfig(config);

        } catch (ServerConfig.ConfigException e) {
            log.error("configException={}",e.getMessage());
        }catch (IOException e) {
            e.printStackTrace();
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    private ServerCnxnFactory cnxnFactory;


    public void runFromConfig(ServerConfig config) throws IOException,InterruptedException {

        Server server = new Server();

        //CountDownLatch对象可以实现阻塞线程不关闭，实现长连接
        CountDownLatch latch = new CountDownLatch(1);
        server.registerShutDownHandler(new ServerShutDownHandler(latch));


        // 创建连接管理器工厂
        if (config.getClientPortAddress()!=null) {
            cnxnFactory = ServerCnxnFactory.createFactory();
            // 初始化配置
            //1.检测CPU核心数
            //2.创建检测IO的线程
            //3.处理IO的线程
            //4.绑定端口，并创建接收客户端连接的线程，注册到selector上
            cnxnFactory.configure(config.getClientPortAddress(), config.getMaxClientCnxns(), config.getClientPortListenBacklog(), false);
            //启动连接管理器
            //1.启动处理IO的线程池
            //2.启动检测IO的线程
            //3.启动接收客户端的线程
            //4.设置序列化方式
            //5.创建处理业务逻辑的线程池
            cnxnFactory.startup(server);
        }

        try {
            latch.await();
            //执行shutdown操作
            shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private void shutdown() {

        //TODO shutdown
    }
}
